﻿using DotNetCore.CAP;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Reflection;

namespace Microsoft.Extensions.DependencyInjection
{
    /// <summary>
    /// 服务注册
    /// </summary>
    public static class RegisterServiceExtension
    {
        /// <summary>
        /// 自动注入服务，继承了IScopedService、ISingletonService、ITransientService非泛型服务; 
        /// 默认注册默认程序域所有匹配服务
        /// </summary>
        public static IServiceCollection InjectTKService(this IServiceCollection services, Assembly[] assemblies = null)
        {
            if (assemblies == null || assemblies.Length == 0)
            {
                assemblies = AppDomain.CurrentDomain.GetAssemblies();
            }

            var typeList = assemblies.SelectMany(m => m.ExportedTypes).Where(m => m.IsPublic && !m.IsAbstract && m.IsClass && !m.IsInterface && !m.IsGenericType);
            List<Type> interfaces = null;
            var excludeNameList = new List<string> 
            { 
                typeof(ISingletonService).Name, 
                typeof(IScopedService).Name, 
                typeof(ITransientService).Name, 
                typeof(IDisposable).Name, 
                typeof(ICapSubscribe).Name 
            };
            foreach (var item in typeList)
            {
                interfaces = item.GetInterfaces().Where(m => !excludeNameList.Contains(m.Name)).ToList();
                if (typeof(IScopedService).IsAssignableFrom(item))
                {
                    services.Inject(interfaces, ServiceLifetime.Scoped, item);
                }
                else if (typeof(ISingletonService).IsAssignableFrom(item))
                {
                    services.Inject(interfaces, ServiceLifetime.Singleton, item);
                }
                else if (typeof(ITransientService).IsAssignableFrom(item))
                {
                    services.Inject(interfaces, ServiceLifetime.Transient, item);
                }
            }

            return services;
        }

        /// <summary>
        /// 注册服务
        /// </summary>
        private static void Inject(this IServiceCollection services, List<Type> interfaces, ServiceLifetime lifeTime, Type classType)
        {
            if (!interfaces.Any())
            {
                interfaces.Add(classType);
            }

            switch (lifeTime)
            {
                case ServiceLifetime.Singleton:
                    interfaces.ForEach(m => services.TryAddSingleton(m, classType));
                    break;
                case ServiceLifetime.Scoped:
                    interfaces.ForEach(m => services.TryAddScoped(m, classType));
                    break;
                case ServiceLifetime.Transient:
                    interfaces.ForEach(m => services.TryAddTransient(m, classType));
                    break;
            }
        }
    }
}
